<?
class dbdDispatcher
{
	const BUILTIN_PREFIX = "dbd";
	const CONTROLLER_DIR = "controllers";
	const FALLBACK_CONTROLLER = "dbdEmptyController";
	const DEFAULT_CONTROLLER = "index";
	const DEFAULT_ACTION = "default";
	const ACTION_PREFIX = "do";
	const XAJAX_ACTION_PREFIX = "xDo";

	private $router = null;
	private $app_dir = null;
	private $controller_dir = null;

	public function __construct(dbdRouter $router, $app_dir)
	{
		$this->router = $router;
		$this->app_dir = $app_dir;
		$this->controller_dir = dbdLoader::getControllerDir();
	}

	public function dispatch()
	{
		$controller = $this->getController();
		$action = $this->getAction($controller);
		$controller->$action();
	}

	private function getController()
	{
		$controller = $this->router->getController();
		if (empty($controller))
			$controller = $this->router->setController(self::DEFAULT_CONTROLLER);
		if (!preg_match("/^".self::BUILTIN_PREFIX."/", $controller))
		{
			$controller = ucfirst($controller);
			$file = $this->app_dir.$this->controller_dir.DBD_DS.$controller.".php";
			if (!file_exists($file))
				$controller = self::FALLBACK_CONTROLLER;
			else
				require_once($file);
		}
		if (!class_exists($controller))
			throw new dbdException("Controller (".$controller.") class could not be found!");
		$controller = new $controller($this->router, $this->app_dir);
		if ($controller instanceof dbdController)
			return $controller;
		else
			throw new dbdException("Controller (".$controller.") must extend dbdController!");
	}

	private function getAction(dbdController $controller)
	{
		$action = $this->router->getAction();
		if (empty($action))
		{
			$this->router->setAction(self::DEFAULT_ACTION);
			$action = $this->router->getAction();
		}
		$action = self::ACTION_PREFIX.ucfirst($action);
		if (!method_exists($controller, $action))
			throw new dbdException("Action (".$action.") could not be executed!");
		return $action;
	}
}
?>